package org.lex.swing.busyicon;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;

public class BusyIcon extends JLabel {
	private final IBusyIconResource resource;

	private final Timer busyIconTimer;
	private final Lock lock;

	private int busyIconIndex = 0;

	public BusyIcon() {
		this(DefaultBusyIconResource.getInstance());
	}

	public BusyIcon(final IBusyIconResource resource) {
		this.resource = resource;
		this.lock = new ReentrantLock();

		int busyAnimationRate = resource.getAnimationRate();
		busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				busyIconIndex++;
				if (busyIconIndex >= resource.getBusyIcons().length) {
					busyIconIndex = 0;
				}
				setIcon(resource.getBusyIcons()[busyIconIndex]);
			}
		});

		this.setHorizontalAlignment(SwingConstants.LEFT);
		this.setName("statusAnimationLabel");
		this.setIcon(resource.getIdleIcon());
	}

	public void start() {
		try {
			for (; false == lock.tryLock();) {
			}
			if (false == busyIconTimer.isRunning()) {
				this.setIcon(resource.getBusyIcons()[0]);
				busyIconIndex = 0;
				busyIconTimer.start();
			}
		} finally {
			lock.unlock();
		}
	}

	public void stop() {
		try {
			for (; false == lock.tryLock();) {
			}
			if (true == busyIconTimer.isRunning()) {
				busyIconTimer.stop();
				this.setIcon(resource.getIdleIcon());
			}
		} finally {
			lock.unlock();
		}
	}
}
